package util

import (
	"LibraryManagementSys/model/dto"
	"fmt"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	enTranslations "github.com/go-playground/validator/v10/translations/en"
	chTranslations "github.com/go-playground/validator/v10/translations/zh"
	"reflect"
	"strings"
	"time"
)

var Trans ut.Translator

func SignupParamStructLevelValidation(level validator.StructLevel) {
	su := level.Current().Interface().(dto.RegisterParam)
	if su.Password != su.RePassword {
		level.ReportError(su.RePassword, "re_password", "RePassword", "eqfield", "password")
	}
}

func InitTrans(locale string) (err error) {
	v, ok := binding.Validator.Engine().(*validator.Validate)
	if ok {
		//自定义字段名称
		v.RegisterTagNameFunc(func(field reflect.StructField) string {
			jsonTag := field.Tag.Get("json")
			name := strings.SplitN(jsonTag, ",", 2)[0]
			if name == "_" {
				return ""
			}
			return name
		})

		v.RegisterStructValidation(SignupParamStructLevelValidation, dto.RegisterParam{})

		//注册自定义时间校验函数
		err = v.RegisterValidation("checkDate", CheckDate)

		zht := zh.New() //中文翻译器
		ent := en.New()

		//创建一个通用翻译器
		uni := ut.New(zht, zht, ent)

		var ok bool
		//获取指定的翻译器
		Trans, ok = uni.GetTranslator(locale)
		if !ok {
			return fmt.Errorf("uni.GetTranslator(%s),failed\n", locale)
		}
		//注册翻译器
		switch locale {
		case "en":
			err = enTranslations.RegisterDefaultTranslations(v, Trans)
		case "zh":
			err = chTranslations.RegisterDefaultTranslations(v, Trans)
		default:
			err = chTranslations.RegisterDefaultTranslations(v, Trans)

		}
		err = v.RegisterTranslation("checkDate", Trans, RegisterTranslator("checkDate", "{0}必须晚于当前日期"), Translate)

		return
	}
	return
}

// 删除结构体前缀
func RemoveTopStruct(fields map[string]string) map[string]string {
	rsp := map[string]string{}
	for field, err := range fields {
		rsp[field[strings.Index(field, ".")+1:]] = err
	}
	return rsp
}

func CheckDate(level validator.FieldLevel) bool {
	date, err := time.Parse("2006-01-02", level.Field().String())
	if err != nil {
		return false
	}
	if date.Before(time.Now()) {
		return false
	}
	return true
}

func RegisterTranslator(tag string, msg string) validator.RegisterTranslationsFunc {
	return func(ut ut.Translator) error {
		if err := Trans.Add(tag, msg, false); err != nil {
			return err
		}
		return nil
	}
}

func Translate(trans ut.Translator, fieldError validator.FieldError) string {
	msg, err := trans.T(fieldError.Tag(), fieldError.Field())
	if err != nil {
		return fieldError.Error()
	}
	return msg
}
